//
//  Date+Extension.swift
//  Library_y
//
//  Created by JC on 2023/6/6.
//

import Foundation
import UIKit
import ObjectMapper

/// 日期格式
///
/// - _YMDHMS:      yyyy-MM-dd HH:mm:ss
/// - _YMD:         yyyy-MM-dd
/// - YMDHMS:       yyyy年MM月dd日 HH:mm:ss
/// - YMD:          yyyy年MM月dd日
public enum JCDateFormatEnum {
    case _YMDHMS_S
    case _YMDHMS
    case _YMDHM
    case _YMD
    case _MD
    case _MDHMS
    case YMDHMS
    case YMDHM
    case YMD
    case MD
    case MDHMS
    case HM
    case HMS
    case Y
    case M
    case D
    
    /// 日期转换格式
    public var format: String {
        switch self {
        case ._YMDHMS_S:
            return "yyyy-MM-dd HH:mm:ss.SSS"
        case ._YMDHMS:
            return "yyyy-MM-dd HH:mm:ss"
        case ._YMDHM:
            return "yyyy-MM-dd HH:mm"
        case ._YMD:
            return "yyyy-MM-dd"
        case ._MD:
            return "MM-dd"
        case ._MDHMS:
            return "MM-dd HH:mm:ss"
        case .YMDHMS:
            return "yyyy年MM月dd日 HH:mm:ss"
        case .YMDHM:
            return "yyyy年MM月dd日 HH:mm"
        case .YMD:
            return "yyyy年MM月dd日"
        case .MD:
            return "MM月dd日"
        case .MDHMS:
            return "MM月dd日 HH:mm:ss"
        case .HM:
            return "HH:mm"
        case .HMS:
            return "HH:mm:ss"
        case .Y:
            return "yyyy"
        case .M:
            return "MM"
        case .D:
            return "dd"
        }
    }
}

public extension Date {
    
    /// 根据格式返回日期字符串
    ///
    /// - parameter format: 目标格式
    ///
    /// - returns: 日期字符串
    func format(_ type: JCDateFormatEnum = ._YMDHMS) -> String {
        let dfmatter = DateFormatter()
        dfmatter.dateFormat = type.format
        return dfmatter.string(from: self as Date)
    }
    
    /// 根据日期字符串转时间类型
    ///
    /// - Parameters:
    ///   - string: 字符串
    ///   - type: 日期字符串类型
    /// - Returns: 时间类
    func format(_ dateStr: String, _ type: JCDateFormatEnum = ._YMDHMS) -> Date? {
        let dateFormatter = DateFormatter.init()
        dateFormatter.dateFormat = type.format
        let date = dateFormatter.date(from: dateStr)
        return date
    }
    
    /// Date提取 --> 星期
    func getWeekDay() -> String {
        let interval = timeIntervalSince1970
        let days = Int(interval / 86400)
        var weekday = ((days + 4) % 7 + 7) % 7
        weekday = (weekday == 0) ? 7 : weekday
        switch weekday {
        case 1:
            return "星期一"
        case 2:
            return "星期二"
        case 3:
            return "星期三"
        case 4:
            return "星期四"
        case 5:
            return "星期五"
        case 6:
            return "星期六"
        case 7:
            return "星期日"
        default:
            return "nil"
        }
    }
}

extension Date {
    
    /// 通过当前年月，获取1号的星期数
    ///
    /// - Parameters:
    ///   - year: 年
    ///   - month: 月
    /// - Returns: 星期
    public func getCurrentMonthFirstDayWeekday(_ year: Int, _ month: Int) -> Int {
        
        let currentStr = NSString(format: "%d年%d月1日", year, month)
        let currentDate = Tools.stringToDate(currentStr as String, type: .YMD)
        let currentWeekday = currentDate.chineseWeekday
        return currentWeekday
    }
    
    /// 通过年月，获取当年月的天数
    ///
    /// - Parameters:
    ///   - year: 年
    ///   - month: 月
    /// - Returns: 天数
    public func getCurrentMonthDays(_ year: Int, _ month: Int) -> Int {
        let currentStr = NSString(format: "%d年%d月", year, month)
        let dfmatter = DateFormatter()
        dfmatter.dateFormat="yyyy年MM月1日"
        guard let date = dfmatter.date(from: currentStr as String) else { return 0 }
        return date.dayCount
    }
    
    /// 当月有多少天
    public var dayCount: Int {
        return Calendar.current.range(of: .day, in: .month, for: self)?.count ?? 0;
    }
    
    /// 星期
    public var chineseWeekday: Int {
        let week = Calendar.current.component(.weekday, from: self)
        return (week == 1) ? 7 : (week - 1)
    }
}

public extension Date {
    /**
     *  是否为今天
     */
    func isToday() -> Bool{
        let calendar = Calendar.current
        let unit: Set<Calendar.Component> = [.day,.month,.year]
        let nowComps = calendar.dateComponents(unit, from: Date())
        let selfCmps = calendar.dateComponents(unit, from: self)
        
        return (selfCmps.year == nowComps.year) &&
            (selfCmps.month == nowComps.month) &&
            (selfCmps.day == nowComps.day)
        
    }
    
    /**
     *  是否为昨天
     */
    func isYesterday() -> Bool {
        let calendar = Calendar.current
        let unit: Set<Calendar.Component> = [.day,.month,.year]
        let nowComps = calendar.dateComponents(unit, from: Date())
        let selfCmps = calendar.dateComponents(unit, from: self)
        if selfCmps.day == nil || nowComps.day == nil {
            return false
        }
        let count = nowComps.day! - selfCmps.day!
        return (selfCmps.year == nowComps.year) &&
            (selfCmps.month == nowComps.month) &&
            (count == 1)
    }
    /**
     *  是否为今年
     */
    func isThisYear() -> Bool {
        let calendar = Calendar.current
        let nowCmps = calendar.dateComponents([.year], from: Date())
        let selfCmps = calendar.dateComponents([.year], from: self)
        let result = nowCmps.year == selfCmps.year
        return result
    }
}

// MARK: - 计算两个日期之间的跨度
public extension Date {
    
    func daysInBetweenDate(_ date: Date) -> Double {
        return betweenDate(date, type: .day)
    }
    
    func hoursInBetweenDate(_ date: Date) -> Double {
        return betweenDate(date, type: .hour)
    }
    
    func minutesInBetweenDate(_ date: Date) -> Double {
        return betweenDate(date, type: .second)
    }
    
    func secondsInBetweenDate(_ date: Date) -> Double {
        return betweenDate(date, type: .min)
    }
}


fileprivate extension Date {
    func betweenDate(_ date: Date, type: DateBetweenType) -> Double {
        var diff = self.timeIntervalSince1970 - date.timeIntervalSince1970
        diff = fabs(diff/type.diff())
        return diff
    }
}

public enum DateBetweenType{
    case day
    case hour
    case min
    case second
}

fileprivate extension DateBetweenType {
    func diff() -> TimeInterval {
        switch self {
        case .day:
            return 86400
        case .hour:
            return 3600
        case .min:
            return 60
        case .second:
            return 1
        }
    }
}
